﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web.UI;

namespace Star.Tools.Common
{
    public class StringHelper
    {
        #region 自定义的替换字符串函数
        /// <summary>
        /// 自定义的替换字符串函数
        /// </summary>
        /// <param name="SourceString">字符串</param>
        /// <param name="SearchString">替换前字符串</param>
        /// <param name="ReplaceString">替换后字符串</param>
        /// <param name="IsCaseInsensetive"></param>
        /// <returns></returns>
        public static string ReplaceString(string SourceString, string SearchString, string ReplaceString, bool IsCaseInsensetive)
        {
            return Regex.Replace(SourceString, Regex.Escape(SearchString), ReplaceString, IsCaseInsensetive ? RegexOptions.IgnoreCase : RegexOptions.None);
        }


        #endregion

        #region 字符串分割



        /// <summary>
        /// 分割字符串 按着指定分隔符分割字符串
        /// </summary>
        /// <param name="strContent">字符串</param>
        /// <param name="strSplit">分隔符</param>
        /// <returns></returns>
        public static string[] SplitString(string strContent, string strSplit)
        {
            string[] strArray = null;
            if (strContent != null && strContent != "")
            {
                strArray =  Regex.Split(strContent, strSplit, RegexOptions.IgnoreCase);
            }
            return strArray;
            
        }

        /// <summary>
        /// 分割字符串 按着指定分隔符分割字符串 返回指定个数数组
        /// </summary>
        /// <param name="strContent">字符串</param>
        /// <param name="strSplit">分隔符</param>
        /// <param name="p_3">数组个数</param>
        /// <returns></returns>
        public static string[] SplitString(string strContent, string strSplit, int p_3)
        {
            string[] result = new string[p_3];

            string[] splited = SplitString(strContent, strSplit);

            for (int i = 0; i < p_3; i++)
            {
                if (i < splited.Length)
                    result[i] = splited[i];
                else
                    result[i] = string.Empty;
            }

            return result;
        }


        #endregion 字符串分割

        

        #region 取首字母
        /// <summary>
        /// 获取汉字首字母（可包含多个汉字）
        /// </summary>
        /// <Param name="strText"></Param>
        /// <returns></returns>
        public static string GetChineseSpell(string strText)
        {
            int len = strText.Length;
            string myStr = "";
            for (int i = 0; i < len; i++)
            {
                myStr += GetSpell(strText.Substring(i, 1));
            }
            return myStr;
        }

        public static string GetSpell(string cnChar)
        {
            var arrCn = Encoding.Default.GetBytes(cnChar);
            if (arrCn.Length > 1)
            {
                int area = (short)arrCn[0];
                int pos = (short)arrCn[1];
                int code = (area << 8) + pos;
                int[] areacode = { 45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906, 51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481 };
                for (int i = 0; i < 26; i++)
                {
                    int max = 55290;
                    if (i != 25) max = areacode[i + 1];
                    if (areacode[i] <= code && code < max)
                    {
                        return Encoding.Default.GetString(new byte[] { (byte)(65 + i) });
                    }
                }
                return "*";
            }
            return cnChar;
        }

        /// <summary>
        /// 获取第一个汉字的首字母，只能输入汉字
        /// </summary>
        /// <Param name="c"></Param>
        /// <returns></returns>
        public static string GetInitial(string c)
        {
            byte[] array = new byte[2];
            array = System.Text.Encoding.Default.GetBytes(c);
            int i = (short)(array[0] - '\0') * 256 + ((short)(array[1] - '\0'));
            if (i < 0xB0A1) return "*";
            if (i < 0xB0C5) return "A";
            if (i < 0xB2C1) return "B";
            if (i < 0xB4EE) return "C";
            if (i < 0xB6EA) return "D";
            if (i < 0xB7A2) return "E";
            if (i < 0xB8C1) return "F";
            if (i < 0xB9FE) return "G";
            if (i < 0xBBF7) return "H";
            if (i < 0xBFA6) return "J";
            if (i < 0xC0AC) return "K";
            if (i < 0xC2E8) return "L";
            if (i < 0xC4C3) return "M";
            if (i < 0xC5B6) return "N";
            if (i < 0xC5BE) return "O";
            if (i < 0xC6DA) return "P";
            if (i < 0xC8BB) return "Q";
            if (i < 0xC8F6) return "R";
            if (i < 0xCBFA) return "S";
            if (i < 0xCDDA) return "T";
            if (i < 0xCEF4) return "W";
            if (i < 0xD1B9) return "X";
            if (i < 0xD4D1) return "Y";
            if (i < 0xD7FA) return "Z";
            return "*";
        }
        #endregion

        #region 计算匹配率/相似度
        /// <summary>
        /// 计算相似度。
        /// </summary>
        public static SimilarityResult SimilarityRate(string str1, string str2)
        {
            var result = new SimilarityResult();
            var arrChar1 = str1.ToCharArray();
            var arrChar2 = str2.ToCharArray();
            var computeTimes = 0;
            var row = arrChar1.Length + 1;
            var column = arrChar2.Length + 1;
            var matrix = new int[row, column];
            //开始时间
            var beginTime = DateTime.Now;
            //初始化矩阵的第一行和第一列
            for (var i = 0; i < column; i++)
            {
                matrix[0, i] = i;
            }
            for (var i = 0; i < row; i++)
            {
                matrix[i, 0] = i;
            }
            for (var i = 1; i < row; i++)
            {
                for (var j = 1; j < column; j++)
                {
                    var intCost = 0;
                    intCost = arrChar1[i - 1] == arrChar2[j - 1] ? 0 : 1;
                    //关键步骤，计算当前位置值为左边+1、上面+1、左上角+intCost中的最小值 
                    //循环遍历到最后_Matrix[_Row - 1, _Column - 1]即为两个字符串的距离
                    matrix[i, j] = Minimum(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1, matrix[i - 1, j - 1] + intCost);
                    computeTimes++;
                }
            }
            //结束时间
            var endTime = DateTime.Now;
            //相似率 移动次数小于最长的字符串长度的20%算同一题
            var intLength = row > column ? row : column;
            //_Result.Rate = (1 - (double)_Matrix[_Row - 1, _Column - 1] / intLength).ToString().Substring(0, 6);
            result.Rate = (1 - (double)matrix[row - 1, column - 1] / (intLength - 1));
            result.ExeTime = (endTime - beginTime).TotalMilliseconds;
            result.ComputeTimes = computeTimes.ToString() + " 距离为：" + matrix[row - 1, column - 1].ToString();
            return result;
        }
        /// <summary>
        /// 取三个数中的最小值
        /// </summary>
        public static int Minimum(int first, int second, int third)
        {
            var intMin = first;
            if (second < intMin)
            {
                intMin = second;
            }
            if (third < intMin)
            {
                intMin = third;
            }
            return intMin;
        }
        /// <summary>
        /// 计算结果
        /// </summary>
        public struct SimilarityResult
        {
            /// <summary>
            /// 相似度，0.54即54%。
            /// </summary>
            public double Rate;
            /// <summary>
            /// 对比次数
            /// </summary>
            public string ComputeTimes;
            /// <summary>
            /// 执行时间，毫秒
            /// </summary>
            public double ExeTime;
        }
        #endregion

        #region  把字符串按照分隔符转换成List
        /// <summary>
        /// 把字符串按照分隔符转换成 List
        /// </summary>
        /// <param name="str">源字符串</param>
        /// <param name="speater">分隔符</param>
        /// <param name="toLower">是否转换为小写</param>
        /// <returns></returns>
        public static List<string> GetStrArray(string str, char speater, bool toLower)
        {
            List<string> list = new List<string>();
            string[] ss = str.Split(speater);
            foreach (string s in ss)
            {
                if (!string.IsNullOrEmpty(s) && s != speater.ToString())
                {
                    string strVal = s;
                    if (toLower)
                    {
                        strVal = s.ToLower();
                    }
                    list.Add(strVal);
                }
            }
            return list;
        }
        #endregion

        #region 把字符串按照指定分隔符装成List 去除重复
        /// <summary>
        /// 把字符串按照指定分隔符装成 List 去除重复
        /// </summary>
        /// <param name="o_str"></param>
        /// <param name="sepeater"></param>
        /// <returns></returns>
        public static List<string> GetSubStringList(string o_str, char sepeater)
        {
            List<string> list = new List<string>();
            string[] ss = o_str.Split(sepeater);
            foreach (string s in ss)
            {
                if (!string.IsNullOrEmpty(s) && s != sepeater.ToString())
                {
                    list.Add(s);
                }
            }
            return list;
        }



        #endregion


        #region 得到数组列表以逗号分隔的字符串
        /// <summary>
        /// 得到数组列表以逗号分隔的字符串
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public static string GetArrayValueStr(Dictionary<int, int> list)
        {
            StringBuilder sb = new StringBuilder();
            string str;
            foreach (KeyValuePair<int, int> kvp in list)
            {
                sb.Append(kvp.Value + ",");
            }
            if (list.Count > 0)
            {
                str = sb.ToString();

                return str.Substring(0, str.LastIndexOf(","));
            }
            else
            {
                return "";
            }
        }
        #endregion


        #region 字符串其他操作
        /// <summary>
        /// 清理字符串
        /// </summary>
        public static string CleanInput(string strIn)
        {
            return Regex.Replace(strIn.Trim(), @"[^\w\.@-]", "");
        }
        /// <summary>
        /// 去除文本中的html代码。
        /// </summary>
        public static string RemoveHtml(string inputString)
        {
            return System.Text.RegularExpressions.Regex.Replace(inputString, @"<[^>]+>", "");
        }
        //获得干净,无非法字符的字符串
        public static string GetCleanJsString(string str)
        {
            str = str.Replace("\"", "“");
            str = str.Replace("'", "”");
            str = str.Replace("\\", "\\\\");
            Regex re = new Regex(@"\r|\n|\t", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
            str = re.Replace(str, " ");

            return str;
        }


        #endregion

        
#region 全角半角
        /// <summary>
        /// 半角转全角(SBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>        
        public static string ToSBC(string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }


        /// <summary>
        /// 全角转半角(DBC case)
        /// </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToDBC(string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }
        #endregion

        /// <summary>
        /// 从包含中英文的字符串中截取固定长度的一段，inputString为传入字符串，len为截取长度（一个汉字占两个位）。
        /// </summary>
        public static string CutString(string inputString, int len)
        {
            if (inputString == null || inputString == "")
            {
                return "";
            }

            inputString = inputString.Trim();
            byte[] myByte = System.Text.Encoding.Default.GetBytes(inputString);
            if (myByte.Length > len)
            {
                string result = "";
                for (int i = 0; i < inputString.Length; i++)
                {
                    byte[] tempByte = System.Text.Encoding.Default.GetBytes(result);
                    if (tempByte.Length < len)
                    {
                        result += inputString.Substring(i, 1);
                    }
                    else
                    {
                        break;
                    }
                }
                return result + "...";
            }
            else
            {
                return inputString;
            }
        }

        /// <summary>
        /// 从包含中英文的字符串中截取固定长度的一段，inputString为传入字符串，len为截取长度（一个汉字占两个位）。
        /// </summary>
        public static string CutString(string inputString, int len, string end)
        {
            inputString = inputString.Trim();
            byte[] myByte = System.Text.Encoding.Default.GetBytes(inputString);
            if (myByte.Length > len)
            {
                string result = "";
                for (int i = 0; i < inputString.Length; i++)
                {
                    byte[] tempByte = System.Text.Encoding.Default.GetBytes(result);
                    if (tempByte.Length < len)
                    {
                        result += inputString.Substring(i, 1);
                    }
                    else
                    {
                        break;
                    }
                }
                return result + end;
            }
            else
            {
                return inputString;
            }
        }

        #region SQL格式化
        #region 格式化字符串为SQL语句字段
        /// <summary>
        /// 格式化字符串为SQL语句字段
        /// </summary>
        /// <param name="fldList"></param>
        /// <returns></returns>
        public static string GetSQLFildList(string fldList)
        {
            if (fldList == null)
                return "*";
            if (fldList.Trim() == "")
                return "*";
            if (fldList.Trim() == "*")
                return "*";
            //先去掉空格，[]符号
            string strTemp = fldList;
            strTemp = strTemp.Replace(" ", "");
            strTemp = strTemp.Replace("[", "").Replace("]", "");
            //为防止使用保留字，给所有字段加上[]
            strTemp = "[" + strTemp + "]";
            strTemp = strTemp.Replace('，', ',');
            strTemp = strTemp.Replace(",", "],[");
            return strTemp;
        }
        #endregion

        #region 过滤SQL,所有涉及到输入的用户直接输入的地方都要使用
        /// <summary> 
        /// 过滤SQL,所有涉及到输入的用户直接输入的地方都要使用。 
        /// </summary> 
        /// <param name="text">输入内容</param> 
        /// <returns>过滤后的文本</returns> 
        public static string filterSQL(string text)
        {
            text = text.Replace("'", "''");
            text = text.Replace("{", "{");
            text = text.Replace("}", "}");

            return text;
        }
        #endregion


        #region 过滤SQL,将SQL字符串里面的(')转换成('')，再在字符串的两边加上(')
        /// <summary> 
        /// 将SQL字符串里面的(')转换成('')，再在字符串的两边加上(')。 
        /// </summary> 
        /// <param name="text">输入内容</param> 
        /// <returns>过滤后的文本</returns> 
        public static String GetQuotedString(String text)
        {
            return ("'" + filterSQL(text) + "'");
        }
        #endregion
        #endregion
    }
}
